import * as Blockly from 'blockly/core';
import { JavascriptGenerator, javascriptGenerator } from "blockly/javascript";
import { Tanslate } from './translate';
import { getValue } from './com';
import { WorkspaceSvg } from 'blockly/core';
export namespace Logic {
    const blocks = [
        {
            'key': 'logic_boolean',
            'message0': '%1',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'BOOL',
                    'options': [
                        ['%{BKY_LOGIC_BOOLEAN_TRUE}', 'TRUE'],
                        ['%{BKY_LOGIC_BOOLEAN_FALSE}', 'FALSE'],
                    ],
                },
            ],
            'output': 'Boolean',
            'style': 'logic_blocks',
            'tooltip': '%{BKY_LOGIC_BOOLEAN_TOOLTIP}',
            'helpUrl': '%{BKY_LOGIC_BOOLEAN_HELPURL}',
        },
        {
            'key': 'controls_if',
            'message0': '%{BKY_CONTROLS_IF_MSG_IF} %1',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'IF0',
                    'check': 'Boolean',
                },
            ],
            'message1': '%{BKY_CONTROLS_IF_MSG_THEN} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO0',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'logic_blocks',
            'helpUrl': '%{BKY_CONTROLS_IF_HELPURL}',
            'suppressPrefixSuffix': true
        },
        {
            'key': 'controls_ifelse',
            'message0': '%{BKY_CONTROLS_IF_MSG_IF} %1',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'IF0',
                    'check': 'Boolean',
                },
            ],
            'message1': '%{BKY_CONTROLS_IF_MSG_THEN} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO0',
                },
            ],
            'message2': '%{BKY_CONTROLS_IF_MSG_ELSE} %1',
            'args2': [
                {
                    'type': 'input_statement',
                    'name': 'ELSE',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'logic_blocks',
            'tooltip': '%{BKYCONTROLS_IF_TOOLTIP_2}',
            'helpUrl': '%{BKY_CONTROLS_IF_HELPURL}',
            'suppressPrefixSuffix': true,
        },
        {
            'key': 'logic_compare',
            'message0': '%1 %2 %3',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'A',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['=', '=='],
                        ['\u2260', '!='],
                        ['\u200F<', '<'],
                        ['\u200F\u2264', '<='],
                        ['\u200F>', '>'],
                        ['\u200F\u2265', '>='],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'B',
                },
            ],
            'inputsInline': true,
            'output': 'Boolean',
            'style': 'logic_blocks',
            'helpUrl': '%{BKY_LOGIC_COMPARE_HELPURL}'
        },
        {
            'key': 'logic_operation',
            'message0': '%1 %2 %3',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'A',
                    'check': 'Boolean',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['%{BKY_LOGIC_OPERATION_AND}', '&&'],
                        ['%{BKY_LOGIC_OPERATION_OR}', '||'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'B',
                    'check': 'Boolean',
                },
            ],
            'inputsInline': true,
            'output': 'Boolean',
            'style': 'logic_blocks',
            'helpUrl': '%{BKY_LOGIC_OPERATION_HELPURL}',
        },
        {
            'key': 'logic_negate',
            'message0': '%{BKY_LOGIC_NEGATE_TITLE}',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'BOOL',
                    'check': 'Boolean',
                },
            ],
            'output': 'Boolean',
            'style': 'logic_blocks',
            'tooltip': '%{BKY_LOGIC_NEGATE_TOOLTIP}',
            'helpUrl': '%{BKY_LOGIC_NEGATE_HELPURL}',
        },
        {
            'key': 'logic_ternary',
            'message0': '%{BKY_LOGIC_TERNARY_CONDITION} %1',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'IF',
                    'check': 'Boolean',
                },
            ],
            'message1': '%{BKY_LOGIC_TERNARY_IF_TRUE} %1',
            'args1': [
                {
                    'type': 'input_value',
                    'name': 'THEN',
                },
            ],
            'message2': '%{BKY_LOGIC_TERNARY_IF_FALSE} %1',
            'args2': [
                {
                    'type': 'input_value',
                    'name': 'ELSE',
                },
            ],
            'output': null,
            'style': 'logic_blocks',
            'tooltip': '%{BKY_LOGIC_TERNARY_TOOLTIP}',
            'helpUrl': '%{BKY_LOGIC_TERNARY_HELPURL}',
        },
    ]

    export function init() {
        initGenerator()
        Tanslate.tr(blocks).forEach((item: any) => {
            Blockly.Blocks[item.key] = {
                init: function (this: Blockly.Block) {
                    this.jsonInit(item);
                    if (item.key === 'controls_flow_statements') {
                        this.setOnChange((e) => {
                            const ws = this.workspace as WorkspaceSvg;
                            if (
                                !ws.isDragging ||
                                ws.isDragging() ||
                                (e.type !== Blockly.Events.BLOCK_MOVE && e.type !== Blockly.Events.BLOCK_CREATE)
                            ) {
                                return;
                            }
                            this.setWarningText(
                                Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING'],
                            );
                        })
                    }
                }
            }
        })
    }

    export function getTools() {
        const netBlocks = {
            kind: 'category',
            name: Blockly.Msg['logic'],
            "colour": 210,
            contents: [] as any[]
        }
        blocks.forEach((item: any) => {
            netBlocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return netBlocks
    }

    function initGenerator() {

        javascriptGenerator.forBlock['controls_if'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO0');
            const IF0 = getValue(block, generator, 'IF0')
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!IF0) {
                throw new Error(block.id);
            }
            return `if (${IF0}) {\n${lines}\n}\n`;
        }

        javascriptGenerator.forBlock['controls_ifelse'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO0');
            const IF0 = getValue(block, generator, 'IF0')
            const ELSE = block.getInputTargetBlock('ELSE');
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!IF0) {
                throw new Error(block.id);
            }
            return `if (${IF0}) {\n${lines}\n} else {\n${generator.blockToCode(ELSE)}\n}`;
        }

        javascriptGenerator.forBlock['logic_compare'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const OP = getValue(block, generator, 'OP')
            const A = getValue(block, generator, 'A')
            const B = getValue(block, generator, 'B')

            if (!A || !B) {
                throw new Error(block.id);
            }
            return `${A} ${OP} ${B}`;
        }

        javascriptGenerator.forBlock['logic_operation'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const OP = getValue(block, generator, 'OP')
            const A = getValue(block, generator, 'A')
            const B = getValue(block, generator, 'B')

            if (!A || !B) {
                throw new Error(block.id);
            }
            return `${A} ${OP} ${B}`;
        }

        javascriptGenerator.forBlock['logic_negate'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const BOOL = getValue(block, generator, 'BOOL')

            if (!BOOL) {
                throw new Error(block.id);
            }
            return `!${BOOL}`;
        }

        javascriptGenerator.forBlock['logic_ternary'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const IF = getValue(block, generator, 'IF')
            const THEN = getValue(block, generator, 'THEN')
            const ELSE = getValue(block, generator, 'ELSE')

            if (!IF || !THEN || !ELSE) {
                throw new Error(block.id);
            }
            return `${IF} ? ${THEN} : ${ELSE}`;
        }
    }
}